package com.xnyzc.lhy.order.service.impl.order;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.component.config.GlobalConfig;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.MessageConstant;
import com.xnyzc.lhy.common.constant.MethodConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.EOrderType;
import com.xnyzc.lhy.common.penum.order.EOrderStatus;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.EmptyUtil;
import com.xnyzc.lhy.common.util.NumberToChn;
import com.xnyzc.lhy.common.util.StringUtil;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.coupon.OaSysCouponUser;
import com.xnyzc.lhy.order.entity.dictionaries.OaSysDict;
import com.xnyzc.lhy.order.entity.order.*;
import com.xnyzc.lhy.order.entity.param.order.*;
import com.xnyzc.lhy.order.entity.system.OaSysGlobalConfig;
import com.xnyzc.lhy.order.entity.user.OaCUser;
import com.xnyzc.lhy.order.entity.user.OaDUser;
import com.xnyzc.lhy.order.entity.user.OaDUserInfo;
import com.xnyzc.lhy.order.entity.user.wallet.OaCWallet;
import com.xnyzc.lhy.order.entity.vehicle.OaDDriverVehicle;
import com.xnyzc.lhy.order.entity.vehicle.OaSysVehicle;
import com.xnyzc.lhy.order.entity.vehicle.OaSysVehicleMdict;
import com.xnyzc.lhy.order.mapper.coupon.OaSysCouponUserMapper;
import com.xnyzc.lhy.order.mapper.dictionaries.OaSysDictMapper;
import com.xnyzc.lhy.order.mapper.order.*;
import com.xnyzc.lhy.order.mapper.system.OaSysGlobalConfigMapper;
import com.xnyzc.lhy.order.mapper.user.OaCUserMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserInfoMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserMapper;
import com.xnyzc.lhy.order.mapper.user.wallet.OaCWalletMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaDDriverVehicleMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaSysVehicleMapper;
import com.xnyzc.lhy.order.mapper.vehicle.OaSysVehicleMdictMapper;
import com.xnyzc.lhy.order.service.order.IOaOrderCorrelationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 乘客端订单相关 服务实现类
 * </p>
 *
 * @author lhy@xnyzc.com
 * @since 2019-07-18
 */
@Service
@Slf4j
public class OrderCorrelationServiceImpl implements IOaOrderCorrelationService {

    @Autowired
    private OaDUserMapper oaDUserMapper;

    @Autowired
    private OaDOrderMapper oaDOrderMapper;

    @Autowired
    private OaCWalletMapper oaCWalletMapper;

    @Autowired
    private OaCUserMapper oaCUserMapper;

    @Autowired
    private OaCOrderApprovalOfficialMapper oaCOrderApprovalOfficialMapper;

    @Autowired
    private OaCOrderDeptOfficialMapper oaCOrderDeptOfficialMapper;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private OaCOrderPersonalOfficialMapper oaCOrderPersonalOfficialMapper;

    @Autowired
    private OaSysDictMapper oaSysDictMapper;

    @Autowired
    private OaDDriverVehicleMapper oaDDriverVehicleMapper;

    @Autowired
    private OaSysVehicleMapper oaSysVehicleMapper;

    @Autowired
    private OaSysVehicleMdictMapper oaSysVehicleMdictMapper;

    @Autowired
    private OaDUserInfoMapper oaDUserInfoMapper;

    @Autowired
    private OaSysGlobalConfigMapper oaSysGlobalConfigMapper;

    @Autowired
    private OaSysCouponUserMapper oaSysCouponUserMapper;

    @Autowired
    private OaCSelfStrokeMapper oaCSelfStrokeMapper;

    @Autowired
    private OaOrderOtherPriceMapper oaOrderOtherPriceMapper;

    @Autowired
    private OaDOrderCorrelationServiceImpl oaDOrderCorrelationServiceImpl;

    @Autowired
    private RedisCommon redisCommon;

    @Autowired
    private OrderCommon orderCommon;

    @Autowired
    private OaDUserInfoMapper userInfoMapper;


    /**
     * 获取用户订单列表
     *
     * @param type
     * @param page
     * @return
     */
    @Override
    public Rv getUserOrderList(String type, Integer page, Long userId) {
        //必填验证
        if (StringUtils.isBlank(type) || page == null) {
            throw PangException.create(EErrorCode.noData);
        }
        OaCUser user = getUserByToken(userId);
        if (CheckUtil.objIsEmpty(user)) {
            throw PangException.create(EErrorCode.noData);
        }
        //查询审批公务订单
        List<PassengersOrderResults> collectList = new ArrayList<>();
        PassengersOrderResults result = new PassengersOrderResults();
        List<OaCOrderApprovalOfficial> approvalOfficialList = getOrderApprovalOfficialByUserId(user.getUserId(), type);
        if (!EmptyUtil.isEmpty(approvalOfficialList)) {
            for (OaCOrderApprovalOfficial official : approvalOfficialList) {
                result = new PassengersOrderResults();
                result.setOrderTime("");
                result.setTitle(MessageConstant.AUDITOFFICIAL);
                result.setOrderNo(official.getOrderNo());
                result.setEndAddress(official.getEndAddress());
                result.setOrderStatus(official.getOrderStatus());
                if (CheckUtil.objIsNotEmpty(official.getOrderTime())) {
                    result.setOrderTime(DateFormatUtils.format(official.getOrderTime(), "yyyy-MM-dd HH:mm:ss"));
                }
                result.setOrderType(official.getOrderType());
                result.setStartAddress(official.getStartAddress());
                collectList.add(result);
            }
        }
        //查询部门公务订单
        List<OaCOrderDeptOfficial> deptOfficialList = getOrderDeptByUserId(user.getUserId(), type);
        if (!EmptyUtil.isEmpty(deptOfficialList)) {
            for (OaCOrderDeptOfficial official : deptOfficialList) {
                result = new PassengersOrderResults();
                result.setOrderTime("");
                result.setTitle(MessageConstant.DEPTOFFICIAL);
                result.setOrderNo(official.getOrderNo());
                result.setEndAddress(official.getEndAddress());
                result.setOrderStatus(official.getOrderStatus());
                if (CheckUtil.objIsNotEmpty(official.getOrderTime())) {
                    result.setOrderTime(DateFormatUtils.format(official.getOrderTime(), "yyyy-MM-dd HH:mm:ss"));
                }
                result.setOrderType(official.getOrderType());
                result.setStartAddress(official.getStartAddress());
                collectList.add(result);
            }
        }
        //查询自费叫车订单
        List<OaCOrderPersonal> personalList = getOrderPersonalByUserId(user.getUserId(), type);
        if (!EmptyUtil.isEmpty(personalList)) {
            for (OaCOrderPersonal personal : personalList) {
                result = new PassengersOrderResults();
                result.setOrderTime("");
                result.setTitle(MessageConstant.PERSONALCALL);
                result.setOrderNo(personal.getOrderNo());
                result.setEndAddress(personal.getEndAddress());
                result.setOrderStatus(personal.getOrderStatus());
                if (CheckUtil.objIsNotEmpty(personal.getOrderTime())) {
                    result.setOrderTime(DateFormatUtils.format(personal.getOrderTime(), "yyyy-MM-dd HH:mm:ss"));
                }
                result.setOrderType(personal.getOrderType());
                result.setStartAddress(personal.getStartAddress());
                collectList.add(result);
            }
        }
        //查询个人公务订单
        List<OaCOrderPersonalOfficial> personalOfficialList = getOrderPersonalOfficialByUserId(user.getUserId(), type);
        if (!EmptyUtil.isEmpty(personalOfficialList)) {
            for (OaCOrderPersonalOfficial official : personalOfficialList) {
                result = new PassengersOrderResults();
                result.setOrderTime("");
                result.setTitle(MessageConstant.PERSONALOFFICIAL);
                result.setOrderNo(official.getOrderNo());
                result.setEndAddress(official.getEndAddress());
                result.setOrderStatus(official.getOrderStatus());
                if (CheckUtil.objIsNotEmpty(official.getOrderTime())) {
                    result.setOrderTime(DateFormatUtils.format(official.getOrderTime(), "yyyy-MM-dd HH:mm:ss"));
                }
                result.setOrderType(official.getOrderType());
                result.setStartAddress(official.getStartAddress());
                collectList.add(result);
            }
        }
        List<PassengersOrderResults> resultsList = new ArrayList<>();
        if (EmptyUtil.isEmpty(collectList)) {
            return Rv.wrap(EErrorCode.success, resultsList);
        }
        //数据处理
        resultsList = oaDOrderCorrelationServiceImpl.getOrderDataProcessing(collectList, page);
        return Rv.wrap(EErrorCode.success, resultsList);
    }


    /**
     * 查询订单状态字典表
     *
     * @return
     */
    private List<OaSysDict> getOrderDict() {
        QueryWrapper<OaSysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaSysDict.TYPE, "order_status");
        List<OaSysDict> orderDictList = oaSysDictMapper.selectList(queryWrapper);
        return orderDictList;
    }

    /**
     * 通过token查询用户信息
     *
     * @param userId
     * @return
     */
    private OaCUser getUserByToken(Long userId) {
        OaCUser user = oaCUserMapper.selectById(userId);
        return user;
    }

    /**
     * 通过userId查询审批公务订单
     *
     * @param userId
     * @return
     */
    private List<OaCOrderApprovalOfficial> getOrderApprovalOfficialByUserId(Long userId, String type) {
        QueryWrapper<OaCOrderApprovalOfficial> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderApprovalOfficial.USER_ID, userId);
        List<Integer> status = new ArrayList<>();
        status.add(EOrderStatus.cancelOrderNoNeedPayment.getType());
        status.add(EOrderStatus.abnormalEndOrder.getType());
        status.add(EOrderStatus.paymented.getType());
        queryWrapper.eq(OaCOrderApprovalOfficial.APPROVAL_STATUS, 2);
        if (type.equals(GlobalConfig.END)) {
            queryWrapper.in(OaCOrderApprovalOfficial.ORDER_STATUS, status);
        } else {
            queryWrapper.notIn(OaCOrderApprovalOfficial.ORDER_STATUS, status);
        }
        List<OaCOrderApprovalOfficial> approvalOfficialList = oaCOrderApprovalOfficialMapper.selectList(queryWrapper);
        return approvalOfficialList;
    }

    /**
     * 通过userId查询部门公务订单
     *
     * @param userId
     * @return
     */
    private List<OaCOrderDeptOfficial> getOrderDeptByUserId(Long userId, String type) {
        QueryWrapper<OaCOrderDeptOfficial> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderDeptOfficial.USER_ID, userId);
        List<Integer> status = new ArrayList<>();
        status.add(EOrderStatus.cancelOrderNoNeedPayment.getType());
        status.add(EOrderStatus.abnormalEndOrder.getType());
        status.add(EOrderStatus.paymented.getType());
        if (type.equals(GlobalConfig.END)) {
            queryWrapper.in(OaCOrderDeptOfficial.ORDER_STATUS, status);
        } else {
            queryWrapper.notIn(OaCOrderDeptOfficial.ORDER_STATUS, status);
        }
        List<OaCOrderDeptOfficial> deptOfficialList = oaCOrderDeptOfficialMapper.selectList(queryWrapper);
        return deptOfficialList;
    }

    /**
     * 通过userId查询自费叫车订单
     *
     * @param userId
     * @return
     */
    private List<OaCOrderPersonal> getOrderPersonalByUserId(Long userId, String type) {
        QueryWrapper<OaCOrderPersonal> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderPersonal.USER_ID, userId);
        List<Integer> status = new ArrayList<>();
        status.add(EOrderStatus.cancelOrderNoNeedPayment.getType());
        status.add(EOrderStatus.abnormalEndOrder.getType());
        status.add(EOrderStatus.paymented.getType());
        if (type.equals(GlobalConfig.END)) {
            queryWrapper.in(OaCOrderPersonal.ORDER_STATUS, status);
        } else {
            queryWrapper.notIn(OaCOrderPersonal.ORDER_STATUS, status);
        }
        List<OaCOrderPersonal> personalList = oaCOrderPersonalMapper.selectList(queryWrapper);
        return personalList;
    }

    /**
     * 通过userId查询个人公务订单
     *
     * @param userId
     * @return
     */
    private List<OaCOrderPersonalOfficial> getOrderPersonalOfficialByUserId(Long userId, String type) {
        QueryWrapper<OaCOrderPersonalOfficial> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCOrderPersonalOfficial.USER_ID, userId);
        List<Integer> status = new ArrayList<>();
        status.add(EOrderStatus.cancelOrderNoNeedPayment.getType());
        status.add(EOrderStatus.abnormalEndOrder.getType());
        status.add(EOrderStatus.paymented.getType());
        if (type.equals(GlobalConfig.END)) {
            queryWrapper.in(OaCOrderPersonalOfficial.ORDER_STATUS, status);
        } else {
            queryWrapper.notIn(OaCOrderPersonalOfficial.ORDER_STATUS, status);
        }
        List<OaCOrderPersonalOfficial> personalOfficialList = oaCOrderPersonalOfficialMapper.selectList(queryWrapper);
        return personalOfficialList;
    }

    /**
     * 获取行程结束详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getUserOrderTrip(String orderNo) {
        //必填验证
        if (StringUtils.isBlank(orderNo)) {
            throw PangException.create(EErrorCode.noData);
        }
        Long driverId = 0L;
        OrderTripResults results = new OrderTripResults();
        if (orderNo.contains(EOrderType.SPGW.getValue())) {
            OaCOrderApprovalOfficial official = getOrderApprovalOfficialByOrder(orderNo);
            results.setOrderStatus(official.getOrderStatus());
            results.setTotalFee(String.valueOf(official.getTotalFee()));
            driverId = official.getDriverId();
        } else if (orderNo.contains(EOrderType.BMGW.getValue())) {
            OaCOrderDeptOfficial official = getOrderDeptByOrderNo(orderNo);
            results.setOrderStatus(official.getOrderStatus());
            results.setTotalFee(String.valueOf(official.getTotalFee()));
            driverId = official.getDriverId();
        } else if (orderNo.contains(EOrderType.ZFJC.getValue())) {
            OaCOrderPersonal official = getOrderPersonalByOrderNo(orderNo);
            results.setOrderStatus(official.getOrderStatus());
            results.setTotalFee(String.valueOf(official.getTotalFee()));
            driverId = official.getDriverId();
        } else if (orderNo.contains(EOrderType.GRGW.getValue())) {
            OaCOrderPersonalOfficial official = getOrderPersonalOfficialByOrderNo(orderNo);
            results.setOrderStatus(official.getOrderStatus());
            results.setTotalFee(String.valueOf(official.getTotalFee()));
            driverId = official.getDriverId();
        }
        OaDUser dUser = oaDUserMapper.selectById(driverId);
        if (CheckUtil.objIsEmpty(dUser)) {
            throw PangException.create(EErrorCode.noData);
        }
        //查询司机信息
        List<OaDUserInfo> userInfoList = getUserInfoByDriverId(driverId);
        if (EmptyUtil.isEmpty(userInfoList)) {
            throw PangException.create(EErrorCode.noData);
        }
        //查询车辆
        OaSysVehicle vehicle = getVehicleList(driverId);
        if (CheckUtil.objIsEmpty(vehicle)) {
            throw PangException.create(EErrorCode.noData);
        }
        //查询颜色
        String vehColor = getVehicleColor(vehicle.getVehColor());
        //查询车系
        String vehicleBrand = getVehicleBrand(vehicle.getCode());
        results.setDiscountsMoney("");
        results.setOrderNo(orderNo);
        results.setAvatarFileUrl("");
        results.setVehNo(vehicle.getVehNo());
        results.setDriverName(dUser.getDriverName());
        results.setDriverPhone(dUser.getDriverPhone());
        results.setBeenDriving(userInfoList.get(0).getBeenDriving() + MessageConstant.BEENDRIVING);
        results.setVehicleModels(vehicleBrand + " " + "·" + " " + vehColor);
        //司机星级，等算法确定在进行修改
        results.setStar(5);
        return Rv.wrap(EErrorCode.success, results);
    }

    /**
     * 获取支付详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getPayOrderDetails(String orderNo, Long userId) {
        //必填验证
        if (StringUtils.isBlank(orderNo)) {
            throw PangException.create(EErrorCode.noData);
        }
        //查询用户信息
        OaCUser user = getUserByToken(userId);
        if (CheckUtil.objIsEmpty(user)) {
            throw PangException.create(EErrorCode.noData);
        }
        //判断公务额度是否够支付
        OaCWallet wallet = getWalletByUserId(user.getUserId());
        if (CheckUtil.objIsEmpty(wallet)) {
            throw PangException.create(EErrorCode.noData);
        }
        List<PayOrderListResults> resList = new ArrayList<>();
        PayOrderResults results = new PayOrderResults();
        //审批公务表
        results.setIsDeptPay(0);
        if (orderNo.contains(EOrderType.SPGW.getValue())) {
            OaCOrderApprovalOfficial official = getOrderApprovalOfficialByOrder(orderNo);
            //判断公务额度是否够支付
            if (wallet.getDeptOfficialBalance().compareTo(official.getOfficialFee()) != -1) {
                results.setIsDeptPay(1);
            }
            resList = getOrderReturnResults(official.getTotalFee(), official.getBaseFee(), official.getMileageFee(),
                    official.getDurationFee(), official.getDistanceFee(), official.getSelfFee(), official.getOfficialFee());
        }
        //部门公务订单
        else if (orderNo.contains(EOrderType.BMGW.getValue())) {
            OaCOrderDeptOfficial official = getOrderDeptByOrderNo(orderNo);
            //判断公务额度是否够支付
            if (wallet.getDeptOfficialBalance().compareTo(official.getOfficialFee()) != -1) {
                results.setIsDeptPay(1);
            }
            resList = getOrderReturnResults(official.getTotalFee(), official.getBaseFee(), official.getMileageFee(),
                    official.getDurationFee(), official.getDistanceFee(), official.getSelfFee(), official.getOfficialFee());
        }
        //自费叫车订单
        else if (orderNo.contains(EOrderType.ZFJC.getValue())) {
            OaCOrderPersonal official = getOrderPersonalByOrderNo(orderNo);
            resList = getOrderReturnResults(official.getTotalFee(), official.getBaseFee(), official.getMileageFee(),
                    official.getDurationFee(), official.getDistanceFee(), new BigDecimal(0), new BigDecimal(0));
        }
        //个人公务订单
        else if (orderNo.contains(EOrderType.GRGW.getValue())) {
            OaCOrderPersonalOfficial official = getOrderPersonalOfficialByOrderNo(orderNo);
            resList = getOrderReturnResults(official.getTotalFee(), official.getBaseFee(), official.getMileageFee(),
                    official.getDurationFee(), official.getDistanceFee(), official.getSelfFee(), official.getOfficialFee());
            //判断公务额度是否够支付
            if (wallet.getDeptOfficialBalance().compareTo(official.getOfficialFee()) != -1) {
                results.setIsDeptPay(1);
            }
        }
        results.setResultsList(resList);
        results.setDiscountsMoney("");
        Integer couponNum = getCouponByUserId(user.getUserId());
        results.setCouponsNumber(couponNum);
        results.setOrderNo(orderNo);
        List<OaSysGlobalConfig> configList = getGlobalConfig();
        if (EmptyUtil.isNotEmpty(configList)) {
            results.setPrompt(configList.get(0).getPayDetailPrompt());
        } else {
            results.setPrompt("");
        }
        return Rv.wrap(EErrorCode.success, results);
    }

    /**
     * 通过司机id查询车辆
     *
     * @param driverId
     * @return
     */
    private OaSysVehicle getVehicleList(Long driverId) {
        OaSysVehicle vehicle = null;
        QueryWrapper<OaDDriverVehicle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaDDriverVehicle.DRIVER_ID, driverId);
        List<OaDDriverVehicle> vehicleList = oaDDriverVehicleMapper.selectList(queryWrapper);
        if (EmptyUtil.isNotEmpty(vehicleList)) {
            vehicle = oaSysVehicleMapper.selectById(vehicleList.get(0).getVehicleId());
        }
        return vehicle;
    }

    /**
     * 订单展示价格
     *
     * @param totalFee
     * @param baseFee
     * @param mileageFee
     * @param durationFee
     * @param distanceFee
     * @param selfFee
     * @param officialFee
     * @return
     */
    private List<PayOrderListResults> getOrderReturnResults(BigDecimal totalFee, BigDecimal baseFee, BigDecimal mileageFee,
                                                            BigDecimal durationFee, BigDecimal distanceFee, BigDecimal selfFee, BigDecimal officialFee) {
        BigDecimal zero = new BigDecimal(0);
        List<PayOrderListResults> resList = new ArrayList<>();
        if (totalFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.TOTALFEE);
            res.setMoney(String.valueOf(totalFee));
            resList.add(res);
        }
        if (baseFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.BASEFEE);
            res.setMoney(String.valueOf(baseFee));
            resList.add(res);
        }
        if (mileageFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.MILEAGEFEE);
            res.setMoney(String.valueOf(mileageFee));
            resList.add(res);
        }
        if (durationFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.DURATIONFEE);
            res.setMoney(String.valueOf(durationFee));
            resList.add(res);
        }
        if (distanceFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.DISTANCEFEE);
            res.setMoney(String.valueOf(distanceFee));
            resList.add(res);
        }
        if (selfFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.SELFFEE);
            res.setMoney(String.valueOf(selfFee));
            resList.add(res);
        }
        if (officialFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.OFFICIALFEE);
            res.setMoney(String.valueOf(officialFee));
            resList.add(res);
        }
        return resList;
    }

    /**
     * 通过userId查询用户部门
     *
     * @param userId
     * @return
     */
    private OaCWallet getWalletByUserId(Long userId) {
        QueryWrapper<OaCWallet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaCWallet.USER_ID, userId);
        OaCWallet userWallet = oaCWalletMapper.selectOne(queryWrapper);
        return userWallet;
    }

    /**
     * 查询优惠券
     *
     * @param userId
     * @return
     */
    private Integer getCouponByUserId(Long userId) {
        QueryWrapper<OaSysCouponUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaSysCouponUser.USER_ID, userId);
        queryWrapper.eq(OaSysCouponUser.IS_USE, 0);
        queryWrapper.le(OaSysCouponUser.MATURITY_TIME, new Date());
        Integer couponNum = oaSysCouponUserMapper.selectCount(queryWrapper);
        return couponNum;
    }

    /**
     * 查询司机信息
     *
     * @param driverId
     * @return
     */
    private List<OaDUserInfo> getUserInfoByDriverId(Long driverId) {
        //查询车型id
        QueryWrapper<OaDUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaDUserInfo.DRIVER_ID, driverId);
        List<OaDUserInfo> userInfoList = oaDUserInfoMapper.selectList(queryWrapper);
        return userInfoList;
    }

    /**
     * 查询全局配置
     *
     * @return
     */
    private List<OaSysGlobalConfig> getGlobalConfig() {
        QueryWrapper<OaSysGlobalConfig> queryWrapper = new QueryWrapper<>();
        List<OaSysGlobalConfig> configList = oaSysGlobalConfigMapper.selectList(queryWrapper);
        return configList;
    }

    /**
     * 查询车辆字典
     *
     * @param code
     * @return
     */
    private String getVehicleColor(Integer code) {
        QueryWrapper<OaSysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaSysDict.TYPE, "vegicle_color_type");
        queryWrapper.eq(OaSysDict.VALUE, String.valueOf(code));
        OaSysDict colorDict = oaSysDictMapper.selectOne(queryWrapper);
        return colorDict.getLabel();
    }

    /**
     * 通过code查询车系品牌
     *
     * @param code
     * @return
     */
    private String getVehicleBrand(String code) {
        String brand = "";
        QueryWrapper<OaSysVehicleMdict> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OaSysVehicleMdict.CODE, code);
        List<OaSysVehicleMdict> approvalOfficialList = oaSysVehicleMdictMapper.selectList(queryWrapper);
        List<OaSysVehicleMdict> mdictParentList = new ArrayList<>();
        if (EmptyUtil.isNotEmpty(approvalOfficialList)) {
            OaSysVehicleMdict mdict = approvalOfficialList.get(0);
            List<String> parentIdsList = Arrays.asList(mdict.getParentIds().split(","));
            QueryWrapper<OaSysVehicleMdict> mdictQueryWrapper = new QueryWrapper<>();
            mdictQueryWrapper.in(OaSysVehicleMdict.PARENT_ID, parentIdsList);
            mdictParentList = oaSysVehicleMdictMapper.selectList(mdictQueryWrapper);
        }
        if (EmptyUtil.isNotEmpty(mdictParentList)) {
            brand = mdictParentList.get(0).getName() + "" + mdictParentList.get(mdictParentList.size() - 1).getName();
        }
        return brand;
    }

    /**
     * 通过orderNo查询审批公务订单
     *
     * @param orderNo 订单号
     * @return
     */
    public OaCOrderApprovalOfficial getOrderApprovalOfficialByOrder(String orderNo) {
        QueryWrapper<OaCOrderApprovalOfficial> wrapper = new QueryWrapper<>();
        wrapper.eq(OaCOrderApprovalOfficial.ORDER_NO, orderNo);
        return oaCOrderApprovalOfficialMapper.selectOne(wrapper);
    }


    /**
     * 通过orderNo查询部门公务订单
     *
     * @param orderNo
     * @return
     */
    private OaCOrderDeptOfficial getOrderDeptByOrderNo(String orderNo) {
        QueryWrapper<OaCOrderDeptOfficial> wrapper = new QueryWrapper<>();
        wrapper.eq(OaCOrderDeptOfficial.ORDER_NO, orderNo);
        return oaCOrderDeptOfficialMapper.selectOne(wrapper);
    }

    /**
     * 通过orderNo查询自费叫车订单
     *
     * @param orderNo
     * @return
     */
    private OaCOrderPersonal getOrderPersonalByOrderNo(String orderNo) {
        QueryWrapper<OaCOrderPersonal> wrapper = new QueryWrapper<>();
        wrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
        return oaCOrderPersonalMapper.selectOne(wrapper);
    }

    /**
     * 通过orderNo查询个人公务订单
     *
     * @param orderNo
     * @return
     */
    private OaCOrderPersonalOfficial getOrderPersonalOfficialByOrderNo(String orderNo) {
        QueryWrapper<OaCOrderPersonalOfficial> wrapper = new QueryWrapper<>();
        wrapper.eq(OaCOrderPersonalOfficial.ORDER_NO, orderNo);
        return oaCOrderPersonalOfficialMapper.selectOne(wrapper);
    }

    /**
     * 取消订单
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getCancelOrder(String orderNo, Long userId) {
        //必填验证
        OaCUser user = getUserByToken(userId);
        OaCOrder oaCOrder = orderCommon.queryOrderMessage(orderNo);
        OaDOrder oaDOrder = oaDOrderMapper.selectById(orderNo);
        if (StringUtils.isBlank(orderNo) || CheckUtil.objIsEmpty(user) || CheckUtil.objIsEmpty(oaCOrder)) {
            throw PangException.create(EErrorCode.noData);
        }
        //判断 是否可以取消订单
        if (EOrderStatus.cancelOrder(EOrderStatus.findById(oaCOrder.getOrderStatus()))) {
            throw PangException.create(EErrorCode.CancelOrderStatus);
        }
        //判断是否取消过订单
        if (EOrderStatus.findById(oaCOrder.getOrderStatus()) == EOrderStatus.cancelOrderNoNeedPayment) {
            throw PangException.create(EErrorCode.CancelOrder);
        }
        Date date = new Date();
        oaCOrder.setUpdateTime(date);
        oaCOrder.setUpdateUser(user.getUserId()+"");
        oaCOrder.setTotalFee(new BigDecimal("0"));
        oaCOrder.setOrderStatus(EOrderStatus.cancelOrderNoNeedPayment.getType());
        oaCOrder.setIsComment(1);
        //设置司机订单表
        if (CheckUtil.objIsNotEmpty(oaDOrder)) {
            oaDOrder.setOrderStatus(EOrderStatus.cancelOrderNoNeedPayment.getType());
            oaDOrder.setUpdateTime(date);
            oaDOrder.setUpdateUser(user.getUserId());
            oaDOrder.setTotalCost(new BigDecimal("0"));
            oaDOrderMapper.updateById(oaDOrder);
        }
        orderCommon.updateOrder(oaCOrder);
        String phone = StringUtil.isEmpty(oaCOrder.getPassengerPhone(), user.getUserPhone());
        String tailNumber = StringUtil.getPhoneTailNumber(phone, null);

        //向司机端发送取消订单信息
        Long driverId = oaCOrder.getDriverId();
        if (CheckUtil.objIsNotEmpty(driverId)) {
            if (!orderCommon.setDriverIsOrderAndAcceptancOrderStatus(false, true, driverId,"")) {
                log.info("更新司机接单状态失败!");
                throw PangException.create(EErrorCode.cancelAssignVehicleFailure);
            }
        }

        Qd result = Qd.create()
                .add("orderStatus", oaCOrder.getOrderStatus())
                .add("msg", MessageConstant.VOICE_TAIL_NUMBER + NumberToChn.NumberToChn(tailNumber) + MessageConstant.VOICE_PASSENGER + MessageConstant.VOICE_CANCEL_ORDER);
       // NettyServerService.sendMsgToClient(String.valueOf(driverId), NettyMsg.setJsonMsg(MethodConstant.CANCEL_ORDER, JSON.toJSONString(result)));
        //删除rediskey
        String key = RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo;
        if (redisCommon.hashKey(key)) {
            if (CheckUtil.objIsNotEmpty(oaCOrder.getDriverId())) {
                redisCommon.remove(RedisPrefixConstant.ORDER_VEH + oaCOrder.getDriverId());
            }
            if (CheckUtil.objIsNotEmpty(oaCOrder.getUserId())) {
                redisCommon.remove(RedisPrefixConstant.ORDER_USER + oaCOrder.getUserId());
            }
            redisCommon.remove(key);
        }
        return Rv.wrap(EErrorCode.success);
    }

    /**
     * 费用详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public Rv getOrderCostDetail(String orderNo, Long userId) {
        //必填验证
        if (StringUtils.isBlank(orderNo)) {
            throw PangException.create(EErrorCode.noData);
        }
        OaCUser user = getUserByToken(userId);
        if (CheckUtil.objIsEmpty(user)) {
            throw PangException.create(EErrorCode.noData);
        }
        //返回参数
        CostDetailsResults cost = new CostDetailsResults();
        //费用详情中私用费用
        List<PersonalUseResults> personUseList = getPersonalUseList(orderNo);
        //获取私用金额
        OaCSelfStroke stroke = getOaCSelfStroke(orderNo);
        List<PayOrderListResults> costList = new ArrayList<>();
        //其他费用
        List<OaOrderOtherPrice> otherPriceList = new ArrayList<>();
        //审批公务订单
        if (orderNo.contains(EOrderType.SPGW.getValue())) {
            OaCOrderApprovalOfficial official = getOrderApprovalOfficialByOrder(orderNo);
            // 处理数据
            costList = getOrderCostList(official.getBaseFee(), official.getMileageFee(), official.getMilageDistance(),
                    official.getDurationFee(), official.getDurationTime(), official.getDistanceFee(), stroke);
            otherPriceList = getOrderOtherPrice(official.getApprovalOfficialId());
            cost.setActualFee(official.getActualFee() + MessageConstant.MONEY_NAME);
            cost.setTotalFee(official.getTotalFee() + MessageConstant.MONEY_NAME);
        } else if (orderNo.contains(EOrderType.BMGW.getValue())) {
            //部门公务订单
            OaCOrderDeptOfficial official = getOrderDeptByOrderNo(orderNo);
            // 处理数据
            costList = getOrderCostList(official.getBaseFee(), official.getMileageFee(), official.getMilageDistance(),
                    official.getDurationFee(), official.getDurationTime(), official.getDistanceFee(), stroke);
            //其他费用
            otherPriceList = getOrderOtherPrice(official.getDeptOfficialId());
            cost.setActualFee(official.getActualFee() + MessageConstant.MONEY_NAME);
            cost.setTotalFee(official.getTotalFee() + MessageConstant.MONEY_NAME);
        } else if (orderNo.contains(EOrderType.ZFJC.getValue())) {
            //自费
            OaCOrderPersonal official = getOrderPersonalByOrderNo(orderNo);
            costList = getOrderPersonalDetail(official);
            //其他费用
            otherPriceList = getOrderOtherPrice(official.getPersonalId());
            cost.setActualFee(official.getActualFee() + MessageConstant.MONEY_NAME);
            cost.setTotalFee(official.getTotalFee() + MessageConstant.MONEY_NAME);
        } else if (orderNo.contains(EOrderType.GRGW.getValue())) {
            OaCOrderPersonalOfficial official = getOrderPersonalOfficialByOrderNo(orderNo);
            // 处理数据
            costList = getOrderCostList(official.getBaseFee(), official.getMileageFee(), official.getMilageDistance(),
                    official.getDurationFee(), official.getDurationTime(), official.getDistanceFee(), stroke);
            //其他费用
            otherPriceList = getOrderOtherPrice(official.getPersonalOfficialId());
            cost.setActualFee(official.getActualFee() + MessageConstant.MONEY_NAME);
            cost.setTotalFee(official.getTotalFee() + MessageConstant.MONEY_NAME);
        }
        cost.setDiscount("");
        cost.setOtherPriceList(otherPriceList);
        cost.setPayOrderList(costList);
        cost.setPersonalUseList(personUseList);
        cost.setPrompt(MessageConstant.COST_DETAILS_PROMPT);
        return Rv.wrap(EErrorCode.success, cost);
    }

    /**
     * 审批公务订单支付详情
     *
     * @return
     */
    private List<PayOrderListResults> getOrderCostList(BigDecimal baseFee, BigDecimal mileageFee, BigDecimal milageDistance,
                                                       BigDecimal durationFee, BigDecimal durationTime, BigDecimal distanceFee, OaCSelfStroke stroke) {
        BigDecimal zero = new BigDecimal(0);
        List<PayOrderListResults> resList = new ArrayList<>();
        // isBold 展示字体(0-不加粗 1-加粗)
        if (baseFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.BASEFEE);
            res.setIsBold(1);
            res.setMoney(String.valueOf(baseFee));
            resList.add(res);
        }
        if (!CheckUtil.objIsEmpty(stroke)) {
            BigDecimal mileage = mileageFee.add(stroke.getMileageFee());
            PayOrderListResults totalRes = new PayOrderListResults();
            totalRes.setName(MessageConstant.TOTAL_MILEAGEFEE + "(" + milageDistance + MessageConstant.KILOMETRE + ")");
            totalRes.setIsBold(1);
            totalRes.setMoney(mileage + MessageConstant.MONEY_NAME);
            resList.add(totalRes);
            PayOrderListResults officialRes = new PayOrderListResults();
            officialRes.setName(MessageConstant.OFFICIAL_MILEAGEFEE + "(" + milageDistance + MessageConstant.KILOMETRE + ")");
            officialRes.setIsBold(0);
            officialRes.setMoney(mileageFee + MessageConstant.MONEY_NAME);
            resList.add(officialRes);
            PayOrderListResults privateRes = new PayOrderListResults();
            privateRes.setName(MessageConstant.PRIVATE_MILEAGEFEE + "(" + stroke.getMileageDistance() + MessageConstant.KILOMETRE + ")");
            privateRes.setIsBold(0);
            privateRes.setMoney(stroke.getMileageFee() + MessageConstant.MONEY_NAME);
            resList.add(privateRes);
        } else {
            if (mileageFee.compareTo(zero) > 1) {
                PayOrderListResults res = new PayOrderListResults();
                res.setName(MessageConstant.TOTAL_MILEAGEFEE + "(" + milageDistance + MessageConstant.KILOMETRE + ")");
                res.setIsBold(1);
                res.setMoney(String.valueOf(mileageFee));
                resList.add(res);
            }
        }
        if (!CheckUtil.objIsEmpty(stroke)) {
            BigDecimal duration = durationFee.add(stroke.getDurationFee());
            PayOrderListResults totalRes = new PayOrderListResults();
            totalRes.setName(MessageConstant.TOTAL_DURATIONFEE + "(" + durationTime + MessageConstant.MINUTES + ")");
            totalRes.setIsBold(1);
            totalRes.setMoney(duration + MessageConstant.MONEY_NAME);
            resList.add(totalRes);
            PayOrderListResults privateRes = new PayOrderListResults();
            privateRes.setName(MessageConstant.PRIVATE + "(" + stroke.getDurationTime() + MessageConstant.MINUTES + ")");
            privateRes.setIsBold(0);
            privateRes.setMoney(stroke.getDurationFee() + MessageConstant.MONEY_NAME);
            resList.add(privateRes);
            PayOrderListResults officialRes = new PayOrderListResults();
            officialRes.setName(MessageConstant.OFFICIAL + "(" + durationTime + MessageConstant.MINUTES + ")");
            officialRes.setIsBold(0);
            officialRes.setMoney(durationFee + MessageConstant.MONEY_NAME);
            resList.add(officialRes);
        } else {
            if (durationFee.compareTo(zero) > 1) {
                PayOrderListResults res = new PayOrderListResults();
                res.setName(MessageConstant.TOTAL_DURATIONFEE + "(" + durationTime + MessageConstant.MINUTES + ")");
                res.setIsBold(1);
                res.setMoney(String.valueOf(durationFee));
                resList.add(res);
            }
        }
        if (distanceFee.compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.DURATIONFEE);
            res.setIsBold(1);
            res.setMoney(distanceFee + MessageConstant.MONEY_NAME);
            resList.add(res);
        }
        return resList;
    }

    /**
     * 自费叫车订单支付详情
     *
     * @param official
     * @return
     */
    private List<PayOrderListResults> getOrderPersonalDetail(OaCOrderPersonal official) {
        BigDecimal zero = new BigDecimal(0);
        List<PayOrderListResults> resList = new ArrayList<>();
        // isBold 展示字体(0-不加粗 1-加粗)
        if (official.getBaseFee().compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.BASEFEE);
            res.setIsBold(1);
            res.setMoney(String.valueOf(official.getBaseFee()));
            resList.add(res);
        }
        if (official.getMileageFee().compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.MILEAGEFEE);
            res.setIsBold(1);
            res.setMoney(String.valueOf(official.getMileageFee()));
            resList.add(res);
        }
        if (official.getDurationFee().compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.DURATIONFEE);
            res.setIsBold(1);
            res.setMoney(String.valueOf(official.getDurationFee()));
            resList.add(res);
        }
        if (official.getDistanceFee().compareTo(zero) > 1) {
            PayOrderListResults res = new PayOrderListResults();
            res.setName(MessageConstant.DURATIONFEE);
            res.setIsBold(1);
            res.setMoney(official.getDistanceFee() + MessageConstant.MONEY_NAME);
            resList.add(res);
        }
        return resList;
    }

    /**
     * 费用详情中私用费用
     *
     * @param orderNo
     * @return
     */
    private List<PersonalUseResults> getPersonalUseList(String orderNo) {
        List<PersonalUseResults> personList = new ArrayList<>();
        QueryWrapper<OaCSelfStroke> wrapper = new QueryWrapper<>();
        wrapper.in(OaCSelfStroke.ORDER_NO, orderNo);
        List<OaCSelfStroke> strokeList = oaCSelfStrokeMapper.selectList(wrapper);
        if (strokeList != null || !strokeList.isEmpty()) {
            PersonalUseResults person = new PersonalUseResults();
            for (OaCSelfStroke s : strokeList) {
                person = new PersonalUseResults();
                person.setTime(oaDOrderCorrelationServiceImpl.getDateConversion(s.getStartTime()) + "~" + oaDOrderCorrelationServiceImpl.getDateConversion(s.getEndTime()));
                person.setStartAddress(s.getStartAddress());
                person.setEndAddress(s.getEndAddress());
                person.setStrokeTotalFee(s.getStrokeTotalFee() + MessageConstant.MONEY_NAME);
                personList.add(person);
            }
        }
        return personList;
    }

    /**
     * 费用详情私用价格
     *
     * @param orderNo
     * @return
     */
    private List<OaOrderOtherPrice> getOrderOtherPrice(Long orderNo) {
        QueryWrapper<OaOrderOtherPrice> wrapper = new QueryWrapper<>();
        wrapper.in(OaOrderOtherPrice.ORDER_NO, orderNo);
        List<OaOrderOtherPrice> otherPriceList = oaOrderOtherPriceMapper.selectList(wrapper);
        return otherPriceList;
    }

    /**
     * 费用详情私用价格
     *
     * @param orderNo
     * @return
     */
    private OaCSelfStroke getOaCSelfStroke(String orderNo) {
        OaCSelfStroke strokeResult = new OaCSelfStroke();
        QueryWrapper<OaCSelfStroke> wrapper = new QueryWrapper<>();
        wrapper.in(OaCSelfStroke.ORDER_NO, orderNo);
        List<OaCSelfStroke> strokeList = oaCSelfStrokeMapper.selectList(wrapper);
        if (strokeList != null || !strokeList.isEmpty()) {
            for (OaCSelfStroke stroke : strokeList) {
                strokeResult.setDurationFee(stroke.getDurationFee().add(strokeResult.getDurationFee()));
                strokeResult.setDurationTime(stroke.getDurationTime().add(strokeResult.getDurationTime()));
                strokeResult.setMileageFee(stroke.getMileageFee().add(strokeResult.getMileageFee()));
                strokeResult.setMileageDistance(stroke.getMileageDistance().add(strokeResult.getMileageDistance()));
                strokeResult.setStrokeTotalFee(stroke.getStrokeTotalFee().add(strokeResult.getStrokeTotalFee()));
            }
        }
        return strokeResult;
    }

}
